package top.callback.inf.beautyleaf.starter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import top.callback.inf.beautyleaf.common.utils.MybatisHelper;
import top.callback.inf.beautyleaf.segment.SegmentIDGenerator;
import top.callback.inf.beautyleaf.snowflake.SnowflakeIDGenerator;
import top.callback.inf.beautyleaf.starter.config.BeautyLeafProperties;
import top.callback.inf.beautyleaf.starter.config.DatasourceProperties;

import javax.sql.DataSource;

/**
 * BeautyLeaf 自动配置
 *
 * @author Pengyu Gan
 * CreateDate 2021/3/25
 */
@Slf4j
@Configuration
@EnableConfigurationProperties({BeautyLeafProperties.class, DatasourceProperties.class})
public class BeautyLeafAutoConfig {

    @Autowired
    private BeautyLeafProperties beautyLeafProperties;

    @Autowired
    private DatasourceProperties datasourceProperties;

    @Autowired
    private DataSource dataSource;

    /**
     * 注入号码段算法 ID 生成器
     * @return 号码段算法 ID 生成器
     */
    @Bean
    @ConditionalOnMissingBean(SegmentIDGenerator.class)
    public SegmentIDGenerator segmentIDGenerator() {
        MybatisHelper helper;
        if (beautyLeafProperties.isEnableIndependentDatasource()) {
            helper = new MybatisHelper(
                    datasourceProperties.getDriverClassName(),
                    datasourceProperties.getUrl(),
                    datasourceProperties.getUsername(),
                    datasourceProperties.getPassword());
            log.info("SegmentIDGenerator 使用独立数据源向数据库建立连接。");
        } else {
            if (null == dataSource) {
                log.error("没有找到数据源。");
                throw new RuntimeException("没有找到数据源，请开启 beauty.enable-independent-datasource 使用独立数据源。");
            }
            log.info("SegmentIDGenerator 使用项目数据源向数据库建立连接。");
            helper = new MybatisHelper(dataSource);
        }
        SegmentIDGenerator idGenerator = new SegmentIDGenerator(
                beautyLeafProperties.getKeepConsistencePeriod(),
                beautyLeafProperties.getLoadSegmentThreshold(),
                helper);
        if (idGenerator.init()) {
            log.info("Spring Bean SegmentIDGenerator 创建成功。");
            return idGenerator;
        }
        throw new RuntimeException("Spring Bean SegmentIDGenerator 创建失败。");
    }

    /**
     * 注入雪花算法 ID 生成器
     * @return 雪花算法 ID 生成器
     */
    @Bean
    @ConditionalOnMissingBean(SnowflakeIDGenerator.class)
    public SnowflakeIDGenerator snowflakeIDGenerator() {
        SnowflakeIDGenerator idGenerator = new SnowflakeIDGenerator(
                beautyLeafProperties.getInstanceName(),
                beautyLeafProperties.getInstancePort(),
                beautyLeafProperties.getZookeeperAddress(),
                beautyLeafProperties.getZookeeperConnectionTimeout(),
                beautyLeafProperties.getZookeeperSessionTimeout(),
                beautyLeafProperties.getInstanceTwepoch());
        log.info("Spring Bean SnowflakeIDGenerator 创建成功。");
        return idGenerator;
    }

}
